import {getMongoConnect,promiseUtil} from '../utils';
var Promise = require('es6-promise').Promise;

class BaseService {

    /**
     * 创建一个执行对象
     * @param callback 一个回调函数。该回调函数有三个参数：
     *             client:mongo的连接MongoClient对象.
     *             onFulfilled：完成时候的function，可以把值传给它.
     *             onRejected:被拒绝（发生错误）时候的function，可以把错误信息传给它.
     * @returns 一个Promise执行对象
     *
     * 用法示例：
     *      this.buildExecute((client, onFulfilled, onRejected) => {
     *          client.collection('').find().next(function (err, doc) {
     *              if (err) {
     *                  return onRejected(err);
     *              }
     *              onFulfilled(doc);
     *          });
     *      });
     *
     */
    buildExecute(callback) {

        function _buildErrorInfo(err) {
            return new Error(err.message);
        }

        return new Promise(function (resolve, reject) {
            getMongoConnect((err, client, release)=> {
                if (err) {
                    release();
                    reject(_buildErrorInfo(err));
                }

                callback(client, (res)=> {
                    release();
                    resolve(res);
                }, (err)=> {
                    release();
                    reject(_buildErrorInfo(err));
                });

            });
        });
    }

    /**
     * 同时开始执行tasks中的任务。
     * @param tasks 要执行的任务（方法数组）
     * @param onSuccess 成功时候的function
     * @param onFailure 失败时候的function
     *
     * 用法示例：
     *    let me = this;
     *    let exec = function () {
     *           return me.buildExecute((client, onFulfilled, onRejected) => {
     *               client.collection('org').find({id: parseInt(id)}).limit(1).next(function (err, doc) {
     *                   if (err) {
     *                       return onRejected(err);
     *                   }
     *                   onFulfilled(doc);
     *               });
     *           });
     *       }
     *
     *    super.allExecute([exec], (results)=> {
     *           callback(null, results);
     *       }, (err)=> {
     *           callback(err, null);
     *       });
     */
    allExecute(tasks, onSuccess, onFailure) {
        promiseUtil.runInConcurrent(tasks).then(results => {
            onSuccess(results);
        }).catch(err=> {
            onFailure(err);
        })
    }

    /**
     * 按照tasks中的顺序逐个执行。
     * @param tasks 要执行的任务（方法数组）
     * @param onSuccess 成功时候的function
     * @param onFailure 失败时候的function
     *
     * 用法示例：
     *    let me = this;
     *    let exec = function () {
     *           return me.buildExecute((client, onFulfilled, onRejected) => {
     *               client.collection('org').find({id: parseInt(id)}).limit(1).next(function (err, doc) {
     *                   if (err) {
     *                       return onRejected(err);
     *                   }
     *                   onFulfilled(doc);
     *               });
     *           });
     *       }
     *
     *    super.seqExecute([exec], (results)=> {
     *           callback(null, results);
     *       }, (err)=> {
     *           callback(err, null);
     *       });
     */
    seqExecute(tasks, onSuccess, onFailure) {
        promiseUtil.runInSequence(tasks).then(results => {
            onSuccess(results);
        }).catch(err=> {
            onFailure(err);
        })
    }

    /**
     * 同时执行max个tasks中的任务
     * @param tasks 要执行的任务（方法数组）
     * @param onSuccess 成功时候的function
     * @param onFailure 失败时候的function
     *
     * 用法示例：
     *    let me = this;
     *    let exec = function () {
     *           return me.buildExecute((client, onFulfilled, onRejected) => {
     *               client.collection('org').find({id: parseInt(id)}).limit(1).next(function (err, doc) {
     *                   if (err) {
     *                       return onRejected(err);
     *                   }
     *                   onFulfilled(doc);
     *               });
     *           });
     *       }
     *
     *    super.limitExecute([exec], (results)=> {
     *           callback(null, results);
     *       }, (err)=> {
     *           callback(err, null);
     *       });
     */
    limitExecute(tasks, max, onSuccess, onFailure) {
        promiseUtil.runInMaxConcurrent(tasks, max).then(results => {
            onSuccess(results);
        }).catch(err=> {
            onFailure(err);
        })
    }

}

export default BaseService;
